<!DOCTYPE html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WebSocket 通信测试</title>
  <style>
    body {
      font-family: 'Microsoft YaHei', Arial, sans-serif;
      max-width: 800px;
      margin: 0 auto;
      padding: 20px;
      background-color: #f5f5f5;
    }

    .container {
      background: white;
      padding: 30px;
      border-radius: 10px;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    }

    h1 {
      color: #333;
      text-align: center;
      margin-bottom: 30px;
    }

    .status {
      padding: 15px;
      margin: 20px 0;
      border-radius: 5px;
      font-weight: bold;
    }

    .connected {
      background-color: #d4edda;
      color: #155724;
      border: 1px solid #c3e6cb;
    }

    .disconnected {
      background-color: #f8d7da;
      color: #721c24;
      border: 1px solid #f5c6cb;
    }

    .message-area {
      margin: 20px 0;
    }

    .message-input {
      width: 100%;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 5px;
      margin-bottom: 10px;
      font-size: 16px;
    }

    .send-btn {
      background-color: #007bff;
      color: white;
      border: none;
      padding: 10px 20px;
      border-radius: 5px;
      cursor: pointer;
      font-size: 16px;
    }

    .send-btn:hover {
      background-color: #0056b3;
    }

    .send-btn:disabled {
      background-color: #6c757d;
      cursor: not-allowed;
    }

    .messages {
      background-color: #f8f9fa;
      border: 1px solid #dee2e6;
      border-radius: 5px;
      padding: 15px;
      height: 300px;
      overflow-y: auto;
      margin-top: 20px;
    }

    .message {
      margin: 10px 0;
      padding: 10px;
      border-radius: 5px;
    }

    .message.sent {
      background-color: #d1ecf1;
      border-left: 4px solid #17a2b8;
    }

    .message.received {
      background-color: #d4edda;
      border-left: 4px solid #28a745;
    }

    .timestamp {
      font-size: 12px;
      color: #6c757d;
      margin-top: 5px;
    }

    .controls {
      text-align: center;
      margin: 20px 0;
    }

    .control-btn {
      margin: 0 10px;
      padding: 10px 20px;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      font-size: 16px;
    }

    .connect-btn {
      background-color: #28a745;
      color: white;
    }

    .disconnect-btn {
      background-color: #dc3545;
      color: white;
    }

    .clear-btn {
      background-color: #6c757d;
      color: white;
    }
  </style>
</head>

<body>
  <div class="container">
    <h1>🔌 WebSocket 通信测试</h1>

    <!-- 连接状态显示 -->
    <div id="status" class="status disconnected">
      状态：未连接
    </div>

    <!-- 控制按钮 -->
    <div class="controls">
      <button id="connectBtn" class="control-btn connect-btn">连接</button>
      <button id="disconnectBtn" class="control-btn disconnect-btn" disabled>断开</button>
      <button id="clearBtn" class="control-btn clear-btn">清空消息</button>
    </div>

    <!-- 消息发送区域 -->
    <div class="message-area">
      <input type="text" id="messageInput" class="message-input" placeholder="输入要发送的消息..." disabled>
      <button id="sendBtn" class="send-btn" disabled>发送消息</button>
    </div>

    <!-- 消息显示区域 -->
    <div class="messages" id="messages"></div>
  </div>

  <script>
    class WebSocketClient {
      constructor() {
        this.ws = null;
        this.isConnected = false;
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 5;
        this.reconnectDelay = 1000;

        this.initElements();
        this.bindEvents();
      }

      initElements() {
        this.statusEl = document.getElementById('status');
        this.connectBtn = document.getElementById('connectBtn');
        this.disconnectBtn = document.getElementById('disconnectBtn');
        this.clearBtn = document.getElementById('clearBtn');
        this.messageInput = document.getElementById('messageInput');
        this.sendBtn = document.getElementById('sendBtn');
        this.messagesEl = document.getElementById('messages');
      }

      bindEvents() {
        this.connectBtn.addEventListener('click', () => this.connect());
        this.disconnectBtn.addEventListener('click', () => this.disconnect());
        this.clearBtn.addEventListener('click', () => this.clearMessages());
        this.sendBtn.addEventListener('click', () => this.sendMessage());
        this.messageInput.addEventListener('keypress', (e) => {
          if (e.key === 'Enter') {
            this.sendMessage();
          }
        });
      }

      connect() {
        try {
          // 创建 WebSocket 连接，连接到服务器的 /ws 端点
          this.ws = new WebSocket('ws://127.0.0.1:8000/ws');

          this.ws.onopen = () => {
            this.isConnected = true;
            this.updateStatus('已连接', true);
            this.updateControls(true);
            this.addMessage('系统', 'WebSocket 连接成功！', 'received');
            this.reconnectAttempts = 0;
          };

          this.ws.onmessage = (event) => {
            this.addMessage('服务器', event.data, 'received');
          };

          this.ws.onclose = (event) => {
            this.isConnected = false;
            this.updateStatus('连接已断开', false);
            this.updateControls(false);
            this.addMessage('系统', 'WebSocket 连接已断开', 'received');

            // 尝试重连
            if (this.reconnectAttempts < this.maxReconnectAttempts) {
              this.reconnectAttempts++;
              this.addMessage('系统', `尝试重连... (${this.reconnectAttempts}/${this.maxReconnectAttempts})`, 'received');
              setTimeout(() => this.connect(), this.reconnectDelay);
            } else {
              this.addMessage('系统', '重连失败，请手动重新连接', 'received');
            }
          };

          this.ws.onerror = (error) => {
            this.addMessage('系统', '连接错误: ' + error.message, 'received');
          };

        } catch (error) {
          this.addMessage('系统', '连接失败: ' + error.message, 'received');
        }
      }

      disconnect() {
        if (this.ws) {
          this.ws.close();
          this.ws = null;
        }
      }

      sendMessage() {
        const message = this.messageInput.value.trim();
        if (message && this.isConnected) {
          this.ws.send(message);
          this.addMessage('我', message, 'sent');
          this.messageInput.value = '';
        }
      }

      addMessage(sender, content, type) {
        const messageDiv = document.createElement('div');
        messageDiv.className = `message ${type}`;

        const timestamp = new Date().toLocaleTimeString();
        messageDiv.innerHTML = `
                    <strong>${sender}:</strong> ${content}
                    <div class="timestamp">${timestamp}</div>
                `;

        this.messagesEl.appendChild(messageDiv);
        this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
      }

      clearMessages() {
        this.messagesEl.innerHTML = '';
      }

      updateStatus(text, connected) {
        this.statusEl.textContent = `状态：${text}`;
        this.statusEl.className = `status ${connected ? 'connected' : 'disconnected'}`;
      }

      updateControls(connected) {
        this.connectBtn.disabled = connected;
        this.disconnectBtn.disabled = !connected;
        this.messageInput.disabled = !connected;
        this.sendBtn.disabled = !connected;
      }
    }

    // 页面加载完成后初始化 WebSocket 客户端
    document.addEventListener('DOMContentLoaded', () => {
      new WebSocketClient();
    });
  </script>
</body>

</html>
<html lang="zh-CN">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>WebSocket 通信测试</title>
  <style>
    body {
      font-family: 'Microsoft YaHei', Arial, sans-serif;
      max-width: 800px;
      margin: 0 auto;
      padding: 20px;
      background-color: #f5f5f5;
    }

    .container {
      background: white;
      padding: 30px;
      border-radius: 10px;
      box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
    }

    h1 {
      color: #333;
      text-align: center;
      margin-bottom: 30px;
    }

    .status {
      padding: 15px;
      margin: 20px 0;
      border-radius: 5px;
      font-weight: bold;
    }

    .connected {
      background-color: #d4edda;
      color: #155724;
      border: 1px solid #c3e6cb;
    }

    .disconnected {
      background-color: #f8d7da;
      color: #721c24;
      border: 1px solid #f5c6cb;
    }

    .message-area {
      margin: 20px 0;
    }

    .message-input {
      width: 100%;
      padding: 10px;
      border: 1px solid #ddd;
      border-radius: 5px;
      margin-bottom: 10px;
      font-size: 16px;
    }

    .send-btn {
      background-color: #007bff;
      color: white;
      border: none;
      padding: 10px 20px;
      border-radius: 5px;
      cursor: pointer;
      font-size: 16px;
    }

    .send-btn:hover {
      background-color: #0056b3;
    }

    .send-btn:disabled {
      background-color: #6c757d;
      cursor: not-allowed;
    }

    .messages {
      background-color: #f8f9fa;
      border: 1px solid #dee2e6;
      border-radius: 5px;
      padding: 15px;
      height: 300px;
      overflow-y: auto;
      margin-top: 20px;
    }

    .message {
      margin: 10px 0;
      padding: 10px;
      border-radius: 5px;
    }

    .message.sent {
      background-color: #d1ecf1;
      border-left: 4px solid #17a2b8;
    }

    .message.received {
      background-color: #d4edda;
      border-left: 4px solid #28a745;
    }

    .timestamp {
      font-size: 12px;
      color: #6c757d;
      margin-top: 5px;
    }

    .controls {
      text-align: center;
      margin: 20px 0;
    }

    .control-btn {
      margin: 0 10px;
      padding: 10px 20px;
      border: none;
      border-radius: 5px;
      cursor: pointer;
      font-size: 16px;
    }

    .connect-btn {
      background-color: #28a745;
      color: white;
    }

    .disconnect-btn {
      background-color: #dc3545;
      color: white;
    }

    .clear-btn {
      background-color: #6c757d;
      color: white;
    }
  </style>
</head>

<body>
  <div class="container">
    <h1>🔌 WebSocket 通信测试</h1>

    <!-- 连接状态显示 -->
    <div id="status" class="status disconnected">
      状态：未连接
    </div>

    <!-- 控制按钮 -->
    <div class="controls">
      <button id="connectBtn" class="control-btn connect-btn">连接</button>
      <button id="disconnectBtn" class="control-btn disconnect-btn" disabled>断开</button>
      <button id="clearBtn" class="control-btn clear-btn">清空消息</button>
    </div>

    <!-- 消息发送区域 -->
    <div class="message-area">
      <input type="text" id="messageInput" class="message-input" placeholder="输入要发送的消息..." disabled>
      <button id="sendBtn" class="send-btn" disabled>发送消息</button>
    </div>

    <!-- 消息显示区域 -->
    <div class="messages" id="messages"></div>
  </div>

  <script>
    class WebSocketClient {
      constructor() {
        this.ws = null;
        this.isConnected = false;
        this.reconnectAttempts = 0;
        this.maxReconnectAttempts = 5;
        this.reconnectDelay = 1000;

        this.initElements();
        this.bindEvents();
      }

      initElements() {
        this.statusEl = document.getElementById('status');
        this.connectBtn = document.getElementById('connectBtn');
        this.disconnectBtn = document.getElementById('disconnectBtn');
        this.clearBtn = document.getElementById('clearBtn');
        this.messageInput = document.getElementById('messageInput');
        this.sendBtn = document.getElementById('sendBtn');
        this.messagesEl = document.getElementById('messages');
      }

      bindEvents() {
        this.connectBtn.addEventListener('click', () => this.connect());
        this.disconnectBtn.addEventListener('click', () => this.disconnect());
        this.clearBtn.addEventListener('click', () => this.clearMessages());
        this.sendBtn.addEventListener('click', () => this.sendMessage());
        this.messageInput.addEventListener('keypress', (e) => {
          if (e.key === 'Enter') {
            this.sendMessage();
          }
        });
      }

      connect() {
        try {
          // 创建 WebSocket 连接，连接到服务器的 /ws 端点
          this.ws = new WebSocket('ws://127.0.0.1:8000/ws');

          this.ws.onopen = () => {
            this.isConnected = true;
            this.updateStatus('已连接', true);
            this.updateControls(true);
            this.addMessage('系统', 'WebSocket 连接成功！', 'received');
            this.reconnectAttempts = 0;
          };

          this.ws.onmessage = (event) => {
            this.addMessage('服务器', event.data, 'received');
          };

          this.ws.onclose = (event) => {
            this.isConnected = false;
            this.updateStatus('连接已断开', false);
            this.updateControls(false);
            this.addMessage('系统', 'WebSocket 连接已断开', 'received');

            // 尝试重连
            if (this.reconnectAttempts < this.maxReconnectAttempts) {
              this.reconnectAttempts++;
              this.addMessage('系统', `尝试重连... (${this.reconnectAttempts}/${this.maxReconnectAttempts})`, 'received');
              setTimeout(() => this.connect(), this.reconnectDelay);
            } else {
              this.addMessage('系统', '重连失败，请手动重新连接', 'received');
            }
          };

          this.ws.onerror = (error) => {
            this.addMessage('系统', '连接错误: ' + error.message, 'received');
          };

        } catch (error) {
          this.addMessage('系统', '连接失败: ' + error.message, 'received');
        }
      }

      disconnect() {
        if (this.ws) {
          this.ws.close();
          this.ws = null;
        }
      }

      sendMessage() {
        const message = this.messageInput.value.trim();
        if (message && this.isConnected) {
          this.ws.send(message);
          this.addMessage('我', message, 'sent');
          this.messageInput.value = '';
        }
      }

      addMessage(sender, content, type) {
        const messageDiv = document.createElement('div');
        messageDiv.className = `message ${type}`;

        const timestamp = new Date().toLocaleTimeString();
        messageDiv.innerHTML = `
                    <strong>${sender}:</strong> ${content}
                    <div class="timestamp">${timestamp}</div>
                `;

        this.messagesEl.appendChild(messageDiv);
        this.messagesEl.scrollTop = this.messagesEl.scrollHeight;
      }

      clearMessages() {
        this.messagesEl.innerHTML = '';
      }

      updateStatus(text, connected) {
        this.statusEl.textContent = `状态：${text}`;
        this.statusEl.className = `status ${connected ? 'connected' : 'disconnected'}`;
      }

      updateControls(connected) {
        this.connectBtn.disabled = connected;
        this.disconnectBtn.disabled = !connected;
        this.messageInput.disabled = !connected;
        this.sendBtn.disabled = !connected;
      }
    }

    // 页面加载完成后初始化 WebSocket 客户端
    document.addEventListener('DOMContentLoaded', () => {
      new WebSocketClient();
    });
  </script>
</body>

</html>